<!DOCTYPE html>
<html>

	<head>
		<title></title>
		<meta charset="UTF-8" />
		<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
		<script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=G3KsOmqT7ruGRgxmU9dtpb4r8kjSlMiy"></script>

		<style type="text/css">
			html {
				height: 100%
			}
			
			body {
				height: 100%;
				margin: 0px;
				padding: 0px
			}
			
			#container {
				height: 100%
			}
		</style>
	</head>

	<body>
		<div id="container"></div>
		<script type="text/javascript">
			var map = new BMap.Map("container");
			var point = new BMap.Point(116.404, 39.915);
			map.centerAndZoom(point, 5);
			map.enableScrollWheelZoom(true);

			/**
			 * 标注点
			 * Marker是一个用来往地图上添加点标记的类。使用它将任何你希望用户看到的兴趣点标注在地图上。
			 * API提供了默认图标样式，您也可以通过Icon类来指定自定义图标。Marker的构造函数的参数为Point和MarkerOptions（可选）。
			 * 注意：当您使用自定义图标时，标注的地理坐标点将位于标注所用图标的中心位置，您可通过Icon的offset属性修改标定位置。
			 */
			//			var marker = new BMap.Marker(point); // 创建标注    
			//			map.addOverlay(marker); // 将标注添加到地图中

			/**
			 * 定义标注图标
			 * 通过Icon类可实现自定义标注的图标，下面示例通过参数MarkerOptions的icon属性进行设置，您也可以使用marker.setIcon()方法。
			 */
			function addMarker(point, index) { // 创建图标对象   
				var myIcon = new BMap.Icon("HBuilder.png", new BMap.Size(23, 25), {
					// 指定定位位置。   
					// 当标注显示在地图上时，其所指向的地理位置距离图标左上    
					// 角各偏移10像素和25像素。您可以看到在本例中该位置即是   
					// 图标中央下端的尖角位置。    
					anchor: new BMap.Size(10, 25),
					// 设置图片偏移。   
					// 当您需要从一幅较大的图片中截取某部分作为标注图标时，您   
					// 需要指定大图的偏移位置，此做法与css sprites技术类似。    
					imageOffset: new BMap.Size(0, 0 - index * 25) // 设置图片偏移    
				});
				//				 创建标注对象并添加到地图   
				//				var marker = new BMap.Marker(point, {
				//					icon: myIcon
				//				});
				var marker = new BMap.Marker(point); // 创建标注    
				/**
				 * 监听标注事件
				 */
				var mymyGeo = new BMap.Geocoder();

				function clickFunc(e) {
					/**
					 * 添加信息窗口
					 * 信息窗口在地图上方的浮动显示HTML内容。
					 * 信息窗口可直接在地图上的任意位置打开，也可以在标注对象上打开（此时信息窗口的坐标与标注的坐标一致）。
					 * 您可以使用InfoWindow来创建一个信息窗实例，
					 * 注意同一时刻地图上只能有一个信息窗口处于打开状态。
					 */
					mymyGeo.getLocation(point, function(rs) {
						var addComp = rs.addressComponents;
						var address = addComp.province + ", " + addComp.city + ", " + addComp.district + ", " + addComp.street + ", " + addComp.streetNumber;
						var opts = {
							width: 120, // 信息窗口宽度    
							height: 60, // 信息窗口高度    
							title: "项目一" // 信息窗口标题   
						}
						var infoWindow = new BMap.InfoWindow(address, opts); // 创建信息窗口对象    
						map.openInfoWindow(infoWindow, point); // 打开信息窗口
					});
					//移除监听事件
					//如下示例中，用户第一次点击地图会触发事件监听函数，在函数内部对事件监听进行了移除，因此后续的点击操作则不会触发监听函数。
					marker.removeEventListener("click", clickFunc);
				}
				marker.addEventListener("click", clickFunc);

				/**
				 * 可拖拽的标注
				 * marker的enableDragging和disableDragging方法可用来开启和关闭标注的拖拽功能。
				 * 默认情况下标注不支持拖拽，您需要调用marker.enableDragging()方法来开启拖拽功能。
				 * 在标注开启拖拽功能后，您可以监听标注的dragend事件来捕获拖拽后标注的最新位置。
				 */
				marker.enableDragging();
				marker.addEventListener("dragend", function(e) {
					alert("当前位置：" + e.point.lng + ", " + e.point.lat);
				});
				map.addOverlay(marker);
			}
			// 随机向地图添加10个标注    
			var bounds = map.getBounds();
			var lngSpan = bounds.maxX - bounds.minX; // ??NaN
			var latSpan = bounds.maxY - bounds.minY; // ??NaN
			for(var i = 0; i < 10; i++) {
				//				var point = new BMap.Point(bounds.minX + lngSpan * (Math.random() * 0.7 + 0.15),
				//					bounds.minY + latSpan * (Math.random() * 0.7 + 0.15));
				var point = new BMap.Point((Math.random() * 100),
					(Math.random() * 100));
				addMarker(point, i);
			}

			/**
			 * 定义构造函数并继承Overlay
			 * 
			 * 首先您需要定义自定义覆盖物的构造函数，通过构造函数参数可以传递一些自由的变量。设置自定义覆盖物对象的prototype属性为Overlay的实例，以便继承覆盖物基类。
			 * 如下示例，我们定义一个名为SquareOverlay的构造函数，它包含中心点和边长两个参数，用来在地图上创建一个方形覆盖物。
			 */
			// 定义自定义覆盖物的构造函数  
			function SquareOverlay(center, length, color) {
				this._center = center;
				this._length = length;
				this._color = color;
			}
			// 继承API的BMap.Overlay
			SquareOverlay.prototype = new BMap.Overlay();
			/**
			 * 初始化自定义覆盖物
			 * 实现initialize方法，当调用map.addOverlay方法时，API会调用此方法。
			 * 当调用map.addOverlay方法添加自定义覆盖物时，API会调用该对象的initialize方法用来初始化覆盖物，在初始化过程中需要创建覆盖物所需要的DOM元素，并添加到地图相应的容器中。
			 * 这里我们选择添加在容器markerPane上。
			 */
			// 实现初始化方法  
			//			SquareOverlay.prototype.initialize = function(map) {
			//				// 保存map对象实例
			//				this._map = map;
			//				// 创建div元素，作为自定义覆盖物的容器
			//				var div = document.createElement("div");
			//				div.style.position = "absolute";
			//				// 可以根据参数设置元素外观
			//				div.style.width = this._length + "px";
			//				div.style.height = this._length + "px";
			//				div.style.background = this._color;
			//				// 将div添加到覆盖物容器中
			//				map.getPanes().markerPane.appendChild(div);
			//				// 保存div实例
			//				this._div = div;
			//				// 需要将div元素作为方法的返回值，当调用该覆盖物的show、
			//				// hide方法，或者对覆盖物进行移除时，API都将操作此元素。
			//				return div;
			//			}
			SquareOverlay.prototype.initialize = function(map) {
				// 保存map对象实例
				this._map = map;
				// 创建div元素，作为自定义覆盖物的容器
				var div = document.createElement("div");
				div.style.position = "absolute";
				// 可以根据参数设置元素外观
				div.style.width = this._length + "px";
				div.style.height = this._length + "px";
				div.style.background = this._color;
				// 将div添加到覆盖物容器中
				map.getPanes().markerPane.appendChild(div);
				// 保存div实例
				this._div = div;
				// 需要将div元素作为方法的返回值，当调用该覆盖物的show、
				// hide方法，或者对覆盖物进行移除时，API都将操作此元素。
				return div;
			}
			/*			
			 地图提供了若干容器供覆盖物展示，通过map.getPanes方法可以得到这些容器元素，它们包括：
			floatPane
			markerMouseTarget
			floatShadow
			labelPane
			markerPane
			mapPane
			*/
			/**
			 * 绘制覆盖物
			 */
			// 实现绘制方法   
			SquareOverlay.prototype.draw = function() {
				// 根据地理坐标转换为像素坐标，并设置给容器    
				var position = this._map.pointToOverlayPixel(this._center);
				this._div.style.left = position.x - this._length / 2 + "px";
				this._div.style.top = position.y - this._length / 2 + "px";
			}
			/**
			 * 移除覆盖物
			 * 当调用map.removeOverlay或者map.clearOverlays方法时，API会自动将initialize方法返回的DOM元素进行移除。
			 */
			/**
			 * 显示和隐藏覆盖物
			 * 自定义覆盖物会自动继承Overlay的show和hide方法，方法会修改由initialize方法返回的DOM元素的style.display属性。
			 * 如果自定义覆盖物元素较为复杂，您也可以自己实现show和hide方法。
			 */
			// 实现显示方法    
			SquareOverlay.prototype.show = function() {
				if(this._div) {
					this._div.style.display = "";
				}
			}
			// 实现隐藏方法  
			SquareOverlay.prototype.hide = function() {
				if(this._div) {
					this._div.style.display = "none";
				}
			}
			// 添加自定义方法   
			SquareOverlay.prototype.toggle = function() {
				if(this._div) {
					if(this._div.style.display == "") {
						this.hide();
					} else {
						this.show();
					}
				}
			}

			// 添加自定义覆盖物   
			var mySquare = new SquareOverlay(map.getCenter(), 100, "red");
			map.addOverlay(mySquare);

			/*
			 * 添加和移除图层
			 * 通过map.addTileLayer方法可向地图添加图层，例如下面代码将显示北京市的交通流量。
			 */
			var traffic = new BMap.TrafficLayer(); // 创建交通流量图层实例      
			map.addTileLayer(traffic); // 将图层添加到地图上
			//			map.removeTileLayer(traffic);                // 将图层移除

			/**
			 * 地址解析服务
			 * 根据地址描述获得坐标信息。
			 * 百度地图API提供Geocoder类进行地址解析，您可以通过Geocoder.getPoint()方法来将一段地址描述转换为一个坐标。
			 * 如下示例，我们将地址“杭州市滨江区英飞特大厦”转换获取该位置的地理经纬度坐标，并在这个位置上添加一个标注。 注意:在调用Geocoder.getPoint()方法时您需要提供地址解析所在的城市（本例为“北京市”）。
			 */
			// 创建地址解析器实例     
			var myGeo = new BMap.Geocoder();
			// 将地址解析结果显示在地图上，并调整地图视野    
			myGeo.getPoint("杭州市湘湖公园", function(point) {
					if(point) {
						var marker = new BMap.Marker(point);
						marker.addEventListener("click", function(e) {
							var pt = point;
							myGeo.getLocation(pt, function(rs) {
								alert(rs.address);
								var addComp = rs.addressComponents;
								alert(addComp.province + ", " + addComp.city + ", " + addComp.district + ", " + addComp.street + ", " + addComp.streetNumber);
							});
						});
						map.centerAndZoom(point, 5);
						map.addOverlay(marker);
					}
				},
				"杭州市");
		</script>
	</body>

</html>